use anchor_lang::prelude::*;

use ethabi_solana::{encode, Address,Bytes,Uint,FixedBytes, Hash,Int,Word,Token, decode, decode_whole,param_type };

extern crate hex;

declare_id!("E4b2wv6TyFBqJXn887kCdqZ5GBxtwvkUvcpHyDXmesbx");

#[program]
pub mod abi {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        msg!("Greetings from: {:?}", ctx.program_id);
        let data1 = Uint::from(123456);
        let token1 = Token::Uint(data1);

        msg!("token1: {:?}", token1);

       let add_str = "8E7fbb49f436d0e8a50c02F631e729A57a9a0aCA";

        let data2 = Address::from_slice(hex::decode(add_str).unwrap().as_slice());
        let token2 = Token::Address(data2);
        msg!("token2: {:?}", token2);

        let token3 = Token::Bytes(vec![1,2,3,4,5]);
        msg!("token3: {:?}", token3);
        let encode_info = encode(&[token1, token2, token3]);

        msg!("encode_info: {:?}", encode_info);
        Ok(())
    }


    pub fn decode_2(ctx: Context<Initialize>, encode_info: Vec<u8>)-> Result<()> {
        let paramtype = [param_type::ParamType::Uint(32),param_type::ParamType::Address, param_type::ParamType::Bytes];
        let tokens = decode(&paramtype, &encode_info).unwrap();
        for token in tokens {
            msg!("tokens: {:?}", token);
        }

        Ok(())

    }
    pub fn decode_uint(ctx: Context<Initialize>, encode_info: Vec<u8>)-> Result<()> {
        let paramtype = [param_type::ParamType::Uint(32)];
        let tokens = decode(&paramtype, &encode_info).unwrap();
        msg!("tokens: {:?}", tokens);
        Ok(())
    }


}

#[derive(Accounts)]
pub struct Initialize {}
